package com.tianzehua.grpc;

import com.tianzehua.proto.*;
import io.grpc.stub.StreamObserver;

import java.util.UUID;

/**
 * StudentsServiceImpl {@link StudentServiceGrpc.StudentServiceImplBase}
 * @author tianzehua
 * @date 2019/03/16
 */
public class StudentsServiceImpl extends StudentServiceGrpc.StudentServiceImplBase {
    /* 流式数据就是一个集合或者是一个迭代器 */

    @Override
    public void getRealNameByUsername(MyRequest request, StreamObserver<MyResponse> responseObserver) {
        System.out.println("getRealNameByUsername接收到客服端消息:" + request.getUsername());

        /* 调用onnext 方法来实现接下来需要处理的业务 */
        responseObserver.onNext(MyResponse.newBuilder().setRealname("张三").build());
        /* 用来标识业务已经完成，将responseObserver返回给客户端 */
        responseObserver.onCompleted();
    }

    @Override
    public void getStudentByAge(StudentRequest request, StreamObserver<StudentResponse> responseObserver) {
        System.out.println("getStudentByAge接收到客户端的消息：" + request.getAge());
        responseObserver.onNext(StudentResponse.newBuilder().setName("张三").setAge(20).setCity("北京").build());
        responseObserver.onNext(StudentResponse.newBuilder().setName("李四").setAge(20).setCity("天津").build());
        responseObserver.onNext(StudentResponse.newBuilder().setName("王五").setAge(20).setCity("上海").build());
        responseObserver.onNext(StudentResponse.newBuilder().setName("赵柳").setAge(20).setCity("广州").build());
        responseObserver.onNext(StudentResponse.newBuilder().setName("田七").setAge(20).setCity("四川").build());
        responseObserver.onNext(StudentResponse.newBuilder().setName("陈八").setAge(20).setCity("山西").build());

        responseObserver.onCompleted();
    }

    @Override
    public StreamObserver<StudentRequest> getStudentWrapperByAges(StreamObserver<StudentResponseList> responseObserver) {
        /* 之所以接收值和返回值不是传统意义上的顺序，是因为这只是一个回调的接口，真正的返回在return中  */
        return new StreamObserver<StudentRequest>() {
            @Override
            public void onNext(StudentRequest value) {
                /* 每次客户端调用onnext方法，服务器端的动作 */
                System.out.println("onNext:"+ value.getAge());
            }

            @Override
            public void onError(Throwable t) {
                System.out.println(t.getMessage());
            }

            @Override
            public void onCompleted() {
               /*  该方法是在客户端完成了所有的流式传输后，调用onCompleted后，服务器端会感知这个方法，并且在这里做出相应的动作 */
                StudentResponse studentResponse = StudentResponse.newBuilder().setName("张三").setAge(20).setCity("西安").build();
                StudentResponse studentResponse2 = StudentResponse.newBuilder().setName("李四").setAge(30).setCity("广州").build();

                StudentResponseList studentResponseList = StudentResponseList.newBuilder()
                        .addStudentResponse(studentResponse)
                        .addStudentResponse(studentResponse2)
                        .build();

                responseObserver.onNext(studentResponseList);
            }
        };
    }

    @Override
    public StreamObserver<StreamResquest> biTalk(StreamObserver<StreamResponse> responseObserver) {
        return new StreamObserver<StreamResquest>(){

            @Override
            public void onNext(StreamResquest value) {
                System.out.println(value.getRequestInfo());

                responseObserver.onNext(StreamResponse.newBuilder().setResponseInfo(UUID.randomUUID().toString()).build());
            }

            @Override
            public void onError(Throwable t) {
                System.out.println(t.getMessage());
            }

            @Override
            public void onCompleted() {
                /* 关闭流 */
                responseObserver.onCompleted();
            }
        };
    }
}
